using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Collections;

namespace AngryNurdz
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        List<BasicShape> cubes;
        Texture2D cubeTexture, meTexture;
        BasicEffect cubeEffect;
        Vector3 cameraPosition = new Vector3(0, 10, -10);
        Vector3 modelPosition = Vector3.Zero;
        float rotation = 0.0f;
        float aspectRatio = 0.0f;
        KeyboardState previousState, currentState;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            cubes = new List<BasicShape>();

            cubes.Add(new BasicShape(new Vector3(1, 1, 1), Vector3.Zero));
            cubes.Add(new BasicShape(new Vector3(1, 1, 1), new Vector3(5, 0, 0)));
            cubes.Add(new BasicShape(new Vector3(1, 1, 1), new Vector3(10, 0, 0)));
            cubes.Add(new BasicShape(new Vector3(1, 1, 1), new Vector3(15, 0, 0)));

            cubeTexture = Content.Load<Texture2D>("CubetacularTexture"); 

            meTexture = Content.Load<Texture2D>("me");
            aspectRatio = GraphicsDevice.Viewport.AspectRatio;
            cubeEffect = new BasicEffect(GraphicsDevice);
            previousState = Keyboard.GetState();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            currentState = Keyboard.GetState();

            if (KeyPressed(Keys.Right))
            {
                cameraPosition.X++;
                modelPosition.X++;
            }

            if (KeyPressed(Keys.Left))
            {
                cameraPosition.X--;
                modelPosition.X--;
            }

            previousState = currentState;

            base.Update(gameTime);
        }

        public bool KeyPressed(Keys k)
        {
            return previousState.IsKeyDown(k) && currentState.IsKeyUp(k);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // Set the World matrix which defines the position of the cube
            cubeEffect.World = Matrix.CreateRotationY(MathHelper.ToRadians(rotation)) *
                Matrix.CreateRotationX(MathHelper.ToRadians(rotation)) * Matrix.CreateTranslation(cubes[0].shapePosition);

            // Set the View matrix which defines the camera and what it's looking at
            cubeEffect.View = Matrix.CreateLookAt(cameraPosition, modelPosition, Vector3.Up);

            // Set the Projection matrix which defines how we see the scene (Field of view)
            cubeEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 1000.0f);

            // Enable textures on the Cube Effect. this is necessary to texture the model
            cubeEffect.TextureEnabled = true;
            cubeEffect.Texture = cubeTexture;
            

            // Enable some pretty lights
            cubeEffect.EnableDefaultLighting();

            cubeEffect.CurrentTechnique = cubeEffect.Techniques["BasicEffect"];

            foreach (BasicShape s in cubes)
                foreach (EffectPass pass in cubeEffect.CurrentTechnique.Passes)
                {
                    pass.Apply();
               
                    s.SetTopTexture(meTexture);
                    s.SetSideTexture(cubeTexture);
                    s.SetBottomTexture(cubeTexture);
                    s.RenderShape(GraphicsDevice, cubeEffect);

                }

            base.Draw(gameTime);
        }
    }
}
